package org.malred.v3.server;

import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * minicat主类
 */
public class Bootstrap {
    /**
     * socket监听的端口号
     */
    private int port = 8080;
    private Map<String, HttpServlet> servletMap = new HashMap<>();

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    /**
     * minicat启动需要初始化展开的一些操作
     */
    public void start() throws Exception {
        //加载解析配置文件,web.xml
        loadServlet();
        /*
         * minicat v1.0,http://localhost:8080,返回固定字符串到页面
         */
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("minicat start on port: " + port);
        /**
         * Minicat3.0版本
         * 需求: 可以请求动态资源(servlet)
         */
        while (true) {
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();
            //封装request和response对象
            Request request = new Request(inputStream);
            Response response = new Response(socket.getOutputStream());
            //根据request的url到map里找是否有对应的静态网页
            if (servletMap.get(request.getUrl()) == null) {
                //没在map里,表示是静态资源请求
                response.outputHtml(request.getUrl());
            } else {
                //在map里,动态资源servlet请求
                HttpServlet httpServlet = servletMap.get(request.getUrl());
                httpServlet.service(request, response);
            }
            response.outputHtml(request.getUrl());
            socket.close();
        }
    }

    /**
     * 加载解析web.xml,初始化servlet
     */
    private void loadServlet() throws Exception {
        //加载配置文件
        InputStream resourceAsStream =
                this.getClass().getClassLoader().getResourceAsStream("web.xml");
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
            //获取根元素
            Element rootElement = document.getRootElement();
            //获取servlet标签list
            List<Element> selectNodes = rootElement.selectNodes("//servlet");
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element = selectNodes.get(i);
                //<servlet-name>malguy</servlet-name>
                Element servletNameEle = (Element) element.selectSingleNode("servlet-name");
                String servletName = servletNameEle.getStringValue();
                //<servlet-class>server.MiniServlet</servlet-class>
                Element servletClassEle = (Element) element.selectSingleNode("servlet-class");
                String servletClass = servletClassEle.getStringValue();
                //根据servlet-name找到对应的mapping,找到url-pattern
                Element servletMapping = (Element) rootElement.selectSingleNode
                        ("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                //url-pattern
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}
